package drds.plus.sql_process.optimizer.execute_plan_optimizer;

import drds.plus.common.jdbc.Parameters;
import drds.plus.common.utils.AddressUtils;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlan;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Join;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.MergeQuery;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Query;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.QueryWithIndex;
import drds.plus.sql_process.utils.UniqueIdGenerator;

import java.util.Map;

/**
 * 添加id 不会改变结构
 */
public class FillRequestIdAndSubRequestId implements ExecutePlanOptimizer {

    String hostname = "";

    public FillRequestIdAndSubRequestId() {
        hostname = AddressUtils.getHostIp() + "_" + System.currentTimeMillis();
    }

    public ExecutePlan optimize(ExecutePlan executePlan, Parameters parameters, Map<String, Object> extraCmd) {
        if (executePlan instanceof Query) {
            fillRequestIdAndSubRequestIdFromRoot(executePlan, 1);
        } else {
            executePlan.setSubRequestId(1l);
            executePlan.setRequestId(UniqueIdGenerator.genRequestID());
            executePlan.setRequestHostName(hostname);
        }
        return executePlan;
    }

    public long fillRequestIdAndSubRequestIdFromRoot(ExecutePlan executePlan, long subRequestId) {
        executePlan.setSubRequestId(subRequestId);
        executePlan.setRequestId(UniqueIdGenerator.genRequestID());
        executePlan.setRequestHostName(hostname);

        if (executePlan instanceof QueryWithIndex && ((QueryWithIndex) executePlan).getSubQuery() != null) {
            subRequestId = this.fillRequestIdAndSubRequestIdFromRoot(((QueryWithIndex) executePlan).getSubQuery(), subRequestId + 1);
        } else if (executePlan instanceof MergeQuery) {
            for (ExecutePlan subExecutePlan : ((MergeQuery) executePlan).getExecutePlanList()) {
                subRequestId = this.fillRequestIdAndSubRequestIdFromRoot(subExecutePlan, subRequestId + 1);
            }
        } else if (executePlan instanceof Join) {
            subRequestId = this.fillRequestIdAndSubRequestIdFromRoot(((Join) executePlan).getLeftNode(), subRequestId + 1);
            subRequestId = this.fillRequestIdAndSubRequestIdFromRoot(((Join) executePlan).getRightNode(), subRequestId + 1);
        }

        return subRequestId;
    }

}
